﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using Caliburn.Micro;
using Coproject.Events;
using Coproject.Framework;
using Coproject.ViewModels.Interfaces;
using Coproject.Web.Models;
using Coproject.Web.Services;

namespace Coproject.ViewModels
{
	[Export(typeof(IToDoItemEditor))]
	[PartCreationPolicy(CreationPolicy.NonShared)]
	public class ToDoItemViewModel : Screen, IToDoItemEditor
	{
		[Import]
		public IEventAggregator EventAggregator { get; set; }

		public ToDoItem Item { get; private set; }

		private bool _isReadOnly;
		public bool IsReadOnly
		{
			get
			{
				return this._isReadOnly;
			}
			set
			{
				this._isReadOnly = value;
				NotifyOfPropertyChange(() => IsReadOnly);
				NotifyOfPropertyChange(() => CanEdit);
				NotifyOfPropertyChange(() => CanCancel);
			}
		}

		public bool CanEdit
		{
			get { return IsReadOnly; }
		}

		public bool CanCancel
		{
			get { return !IsReadOnly; }
		}

		public bool CanSave
		{
			get { return Item.HasChanges && !Item.HasValidationErrors; }
		}

		private CoprojectContext _context;

		public IEnumerable<IResult> Setup(int toDoItemID)
		{
			IsReadOnly = true;

			_context = new CoprojectContext();

			var dataResult = new LoadDataResult<ToDoItem>(
				_context,
				_context.GetToDoItemsQuery().Where(x => x.ToDoItemID == toDoItemID));
			yield return dataResult;

			Item = dataResult.Result.Entities.First();
			NotifyOfPropertyChange(() => Item);

			Item.PropertyChanged += (s, e) => NotifyOfPropertyChange(() => CanSave);
		}

		public void Edit()
		{
			IsReadOnly = false;
		}

		public void Cancel()
		{
			(Item as IEditableObject).CancelEdit();
			IsReadOnly = true;
			#region Fix DataForm bug
			IsReadOnly = false; 
			IsReadOnly = true;
			#endregion
		}

		public IEnumerable<IResult> Save()
		{
			(Item as IEditableObject).EndEdit();
			IsReadOnly = true;
			#region Fix DataForm bug
			IsReadOnly = false; IsReadOnly = true;
			#endregion

			yield return new SaveDataResult(_context);

			EventAggregator.Publish(new ToDoItemUpdatedEvent(Item.ToDoItemID));
		}

		public override void CanClose(Action<bool> callback)
		{
			if (Item.HasChanges)
			{
				var result = MessageBox.Show("Current item was not saved. Do you really want to close it?",
					"Coproject", MessageBoxButton.OKCancel);
				callback(result == MessageBoxResult.OK);
			}
			else
			{
				callback(true);
			}
		}

		protected override void OnDeactivate(bool isClosing)
		{
			if (isClosing && CanCancel)
			{
				Cancel();
			}
		}
	}
}
